home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / HPACK78S.ZIP / error.c < prev    next >
C/C++ Source or Header  |  1992-12-03  |  9KB  |  328 lines

  1. /****************************************************************************
  2. *                                                                            *
  3. *                            HPACK Multi-System Archiver                        *
  4. *                            ===========================                        *
  5. *                                                                            *
  6. *                               Error Handling Routines                        *
  7. *                             ERROR.C  Updated 01/08/91                        *
  8. *                                                                            *
  9. * This program is protected by copyright and as such any use or copying of    *
  10. *  this code for your own purposes directly or indirectly is highly uncool    *
  11. *                      and if you do so there will be....trubble.                *
  12. *                 And remember: We know where your kids go to school.            *
  13. *                                                                            *
  14. *        Copyright 1989 - 1991  Peter C.Gutmann.  All rights reserved        *
  15. *                                                                            *
  16. ****************************************************************************/
  17.  
  18. #ifndef __MSDOS__
  19.   #include <stdarg.h>
  20.   #include <stdio.h>
  21. #endif /* !__MSDOS__ */
  22. #include <stdlib.h>
  23. #ifdef __MAC__
  24.   #include "defs.h"
  25.   #include "arcdir.h"
  26.   #include "error.h"
  27.   #include "errorlvl.h"
  28.   #include "flags.h"
  29.   #include "frontend.h"
  30.   #include "hpacklib.h"
  31.   #include "hpaktext.h"
  32.   #include "system.h"
  33.   #include "crypt.h"
  34.   #include "hpackio.h"
  35.   #include "fastio.h"
  36.   #include "store.h"
  37. #else
  38.   #include "defs.h"
  39.   #include "arcdir.h"
  40.   #include "error.h"
  41.   #include "errorlvl.h"
  42.   #include "flags.h"
  43.   #include "frontend.h"
  44.   #include "hpacklib.h"
  45.   #include "system.h"
  46.   #include "crypt/crypt.h"
  47.   #include "io/hpackio.h"
  48.   #include "io/fastio.h"
  49.   #include "language/hpaktext.h"
  50.   #include "store/store.h"
  51. #endif /* __MAC__ */
  52.  
  53. /* Note that some of the following variables must be initialized to 'empty'
  54.    values initially since we may call error() before they are set to a
  55.    sensible value at runtime.  These variables are: errorFD, dirFileFD,
  56.    workDrive, and oldArcEnd */
  57.  
  58. char errorFileName[ MAX_PATH ];    /* The name of the current output file (used
  59.                                    to delete it in case of error) */
  60. FD errorFD = IO_ERROR;    /* The FD of the current output file.  This MUST be
  61.                            closed before the corresponding errorFileName is
  62.                            deleted.  Not closing it results in loss of disk
  63.                            space since it will still be allocated, but the
  64.                            directory entry for it will have been wiped */
  65.  
  66. char dirFileName[ MAX_PATH ];    /* The name of the directory special info file
  67.                                    (if used) */
  68. FD dirFileFD = IO_ERROR;        /* The FD of the directory special info file */
  69.  
  70. char secFileName[ MAX_PATH ];    /* The name of the security info file (if used */
  71. FD secFileFD = IO_ERROR;        /* The FD of the security infor file */
  72. int secInfoLen;                    /* The length of the security info */
  73.  
  74. #ifdef __MAC__
  75.   FD resourceTmpFD = IO_ERROR;    /* The FD of the temp file for resource forks */
  76. #endif /* __MAC__ */
  77.  
  78. /* The original state of the archive */
  79.  
  80. long oldArcEnd = 0L;    /* The end of the archive before files were [A]dded */
  81. void *oldHdrlistEnd;    /* End of list of file headers before files were [A]dded */
  82. int oldDirEnd;
  83. unsigned int oldDirNameEnd;
  84.  
  85. #ifdef __MSDOS__
  86.   extern int fileErrno;    /* I/O error code */
  87. #endif /* __MSDOS__ */
  88. #ifdef __VMS__
  89.   int translateVMSretVal( const int retVal );
  90. #endif /* __VMS__ */
  91. #ifdef __AMIGA__
  92.   void clearLocks( void );
  93. #endif /* __AMIGA__ */
  94.  
  95. /* The archiveFD.  This must be made global to support multipart archives
  96.    since the low-level read and write routines change it whenever they move
  97.    to another section of a multipart archive */
  98.  
  99. FD archiveFD;
  100.  
  101. /****************************************************************************
  102. *                                                                            *
  103. *                            Exit with an Error Message                        *
  104. *                                                                            *
  105. ****************************************************************************/
  106.  
  107. static BOOLEAN recurseCheck = FALSE;    /* Used to check for recursive calls to error() */
  108.  
  109. /* Exit with an error message.  Note that it may be necessary to call the
  110.    functions endPack(), endArcDir(), endFastIO(), and endMem()/freeFileSpecs().
  111.    However if an error occurs during these functions we will end up doing
  112.    things like dereferencing null pointers unless a lot of extra code is added
  113.    to check for this sort of thing, thus we rely on the .crt0 code to handle
  114.    this */
  115.  
  116. void error( ERROR_INFO *errInfo, ... )
  117.     {
  118. #if !defined( __MSDOS__ ) || defined( GUI )
  119.   #ifdef NO_STDARG
  120.     char buffer[ 20 ];                /* Buffer for string conversions */
  121.     char *format = errInfo->msg;    /* Pointer to format string */
  122.   #endif /* NO_STDARG */
  123.     va_list argPtr;                    /* Argument list pointer */
  124. #endif /* !__MSDOS__ || GUI */
  125.  
  126. #ifndef GUI
  127.     hprintf( MESG_ERROR );            /* Print initial part of error message */
  128. #endif /* !GUI */
  129. #if defined( __MSDOS__ ) && !defined( GUI )
  130.     hvprintf();    /* Print with args off current stack frame + other nastiness */
  131. #elif defined( NO_STDARG )
  132.     /* vprintf() for systems which don't have it.  This only handles the
  133.        very few cases which are present in error messages ('%s', '%c'),
  134.        with two example cases ('%%' and '%d') being included to show how
  135.        these variations would be handled */
  136.     va_start( argPtr, format );
  137.     while( *format )
  138.         {
  139.         if( *format == '%' )
  140.             switch( *++format )
  141.                 {
  142.                 /* String */
  143.                 case 's':
  144.                     fputs( va_arg( argPtr, ( char * ), stdout );
  145.                     format++;
  146.                     break;
  147.  
  148.                 /* Single character */
  149.                 case 'c':
  150.                     putchar( va_arg( argPtr, char ) );
  151.                     format++;
  152.                     break;
  153.  
  154.   #if 0    /* Not needed - included only as an example */
  155.                 /* Percent sign */
  156.                 case '%':
  157.                     putchar( '%' );
  158.                     format++;
  159.                     break;
  160.  
  161.                 /* Decimal integer */
  162.                 case 'd':
  163.                     fputs( itoa( va_arg( argPtr, int ), buffer, 10 ), stdout );
  164.                     format++;
  165.                     break;
  166.   #endif /* 0 */
  167.                 /* Unknown option */
  168.                 default:
  169.                     putchar( *format );
  170.                     format++;
  171.                 }
  172.         else
  173.             {
  174.             putchar( *format );
  175.             format++;
  176.             }
  177.         }
  178.     va_end( argPtr );
  179. #else
  180.     va_start( argPtr, errInfo );    /* Initialize va_ functions    */
  181.     vprintf( errInfo->msg, argPtr );/* Print string */
  182.     va_end( argPtr );                /* Close va_ functions */
  183. #endif /* NO_STDARG */
  184. #ifndef GUI
  185.     hputchar( '\n' );
  186. #endif /* !GUI */
  187.  
  188. #ifdef __AMIGA__
  189.     /* Clear any directory locks still in place, before we do any mungeing
  190.        of files */
  191.     clearLocks();
  192. #endif /* __AMIGA__ */
  193.  
  194.     /* Shut down the encryption system */
  195.     endCrypt();
  196.  
  197.     /* Shut down extraInfo handling */
  198.     endExtraInfo();
  199.  
  200.     /* Do a nasty check for recursive calls to error() via writeArcDir() */
  201.     if( recurseCheck )
  202.         {
  203.         /* Moth detected in relay bank #6 */
  204. #ifdef GUI
  205.         alert( ALERT_ERROR_DURING_ERROR_REC, NULL );
  206. #else
  207.         hputs( MESG_ERROR_DURING_ERROR_RECOVERY );
  208. #endif /* GUI */
  209. #ifdef __VMS__
  210.         exit( translateVMSretVal( EXIT_INT_ERR ) );
  211. #else
  212.         exit( EXIT_INT_ERR );
  213. #endif /* __VMS__ */
  214.         }
  215.     recurseCheck = TRUE;
  216.  
  217.     /* If we had an error during [A]dd, restore the old archive end exit */
  218.     if( oldArcEnd )
  219.         {
  220.         /* Only attempt recovery if we've changed the archive */
  221.         if( archiveChanged )
  222.             {
  223.             hlseek( archiveFD, oldArcEnd + HPACK_ID_SIZE, SEEK_SET );
  224.             setArcdirState( oldHdrlistEnd, oldDirEnd );
  225.             resetFastOut();            /* Clear output buffer */
  226.             writeArcDir();
  227.  
  228.             /* Append the old security and trailer info if necessary */
  229.             if( secFileFD != IO_ERROR )
  230.                 {
  231.                 hlseek( secFileFD, 0, SEEK_SET );
  232.                 hlseek( archiveFD, -( LONG ) ( sizeof( BYTE ) + HPACK_ID_SIZE ), SEEK_CUR );
  233.                 setInputFD( secFileFD );
  234.                 moveData( secInfoLen + sizeof( WORD ) + sizeof( BYTE ) + HPACK_ID_SIZE );
  235.                 flushBuffer();
  236.  
  237.                 /* Zap the security info file */
  238.                 hclose( secFileFD );
  239.                 hunlink( secFileName );
  240.                 }
  241.  
  242.             htruncate( archiveFD );
  243.             hclose( archiveFD );
  244.             }
  245.  
  246.         /* Don't do anything more to archiveFile, secFile or errorFile */
  247.         archiveFD = secFileFD = errorFD = IO_ERROR;
  248.         }
  249.  
  250.     /* Close and delete any necessary files */
  251.     closeFiles();
  252.  
  253. #ifdef __VMS__
  254.     exit( translateVMSretVal( errInfo->errorLevel ) );
  255. #else
  256.     exit( errInfo->errorLevel );
  257. #endif /* __VMS__ */
  258.     }
  259.  
  260. /* Print an OS-specific error message for a file I/O error.  This routine
  261.    is called if an error occurs during a file R/W operation, and thus should
  262.    only be expected to handle problems that will not already have been
  263.    caught in the hopen() call */
  264.  
  265. void fileError( void )
  266.     {
  267. #ifdef __MSDOS__
  268.     ERROR_INFO errInfo;
  269.     errInfo.errorLevel = EXIT_FILE_ERR;
  270.  
  271.     switch( fileErrno )
  272.         {
  273.         case 0x20:
  274.             errInfo.msg = OSMESG_FILE_SHARING_VIOLATION;
  275.             break;
  276.  
  277.         case 0x21:
  278.             errInfo.msg = OSMESG_FILE_LOCKING_VIOLATION;
  279.             break;
  280.  
  281.         default:
  282.             error( FILE_ERROR, fileErrno );
  283.         }
  284.     error( &errInfo );
  285. #else
  286.     error( FILE_ERROR );
  287. #endif
  288.     }
  289.  
  290. /* Close files (and delete incorrect one if need be).  We have to be very
  291.    finicky here since some OS's have rather poor resource management and
  292.    can't keep track of open/closed files themselves */
  293.  
  294. void closeFiles( void )
  295.     {
  296.     if( archiveFD != IO_ERROR )
  297.         {
  298.         hclose( archiveFD );
  299.         archiveFD = IO_ERROR;
  300.         }
  301.     if( errorFD != IO_ERROR )
  302.         {
  303.         hclose( errorFD );
  304.         hunlink( errorFileName );
  305.         errorFD = IO_ERROR;
  306.         }
  307.     if( dirFileFD != IO_ERROR )
  308.         {
  309.         hclose( dirFileFD );
  310.         hunlink( dirFileName );
  311.         dirFileFD = IO_ERROR;
  312.         }
  313.     if( secFileFD != IO_ERROR )
  314.         {
  315.         hclose( secFileFD );
  316.         hunlink( secFileName );
  317.         secFileFD = IO_ERROR;
  318.         }
  319. #ifdef __MAC__
  320.     if( resourceTmpFD != IO_ERROR )
  321.         {
  322.         hclose( resourceTmpFD );
  323.         hunlink( RESOURCE_TMPNAME );
  324.         resourceTmpFD = IO_ERROR;
  325.         }
  326. #endif /* __MAC__ */
  327.     }
  328.